home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 3
/
ct-rom iiib.zip
/
ct-rom iiib
/
OS2
/
SPEL
/
PMGNUCHS
/
PMCHSSRC.ZIP
/
pmchess.c
< prev
next >
Wrap
Text File
|
1994-04-20
|
34KB
|
1,135 lines
/***********************************************************************
* Copyright (C) 1986, 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
* Copyright (c) 1988, 1989, 1990 John Stanback
*
* Project: OS/2 PM Port of GNU CHESS 4.0 (PmChess)
*
* Version: 1994-4-17
*
* Module: Main Module (PmChess.c)
*
* Porter: Gnu Chess 3.0 ported to Windows 3.0 by Darly Baker
*
* Porter: Gnu Chess 3.0 Ported to OS/2 1.2+ by Kent Cedola
*
* Porter: Gnu Chess 4.0 Ported to OS/2 2.1+ by Yibing Fan
*
* System: OS/2 2.11 using emx0.8h
*
* Remarks: Started with bug fixes on Kent's code of PMChess, I then
* start to port gnu chess 4.0. The chess engine now is in three
* seprated threads(the same engine start in 3 different occasions).
* The main trouble is communication between threads. Some data need
* to be passed on fly. In this version, the best line and current
* move in status dialog does not show correctly.
*
* Fuction defined in this module:
* int main(short argc, char **argv)
* void FAR WndCreate(HWND hWnd);
* void FAR WndPaint(HWND hWnd);
* void FAR WndButton(HWND hWnd, ULONG msg, MPARAM mp1);
* void FAR WndDestroy(void);
* FNWP ChessProc;
* FNWP AboutProc;
* MRESULT EXPENTRY NotAvailableDlg( HWND hWnd, ULONG msg, MPARAM mp1,MPARAM mp2);
*
* License:
*
* CHESS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY. No author or distributor accepts responsibility to anyone for
* the consequences of using it or for whether it serves any particular
* purpose or works at all, unless he says so in writing. Refer to the
* CHESS General Public License for full details.
*
* Everyone is granted permission to copy, modify and redistribute CHESS,
* but only under the conditions described in the CHESS General Public
* License. A copy of this license is supposed to have been given to you
* along with CHESS so you can know your rights and responsibilities. It
* should be in a file named COPYING. Among other things, the copyright
* notice and this notice must be preserved on all copies.
****************************************************************************/
#define INCL_DOS
#define INCL_GPI
#define INCL_WIN
#include <os2.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include "PmChess.h"
#include "GnuChess.h"
#include "Defs.h"
#include "Resource.h"
// Thread Variables
TID tidcalc1, tidcalc2, tidcalc3, tiddsp;
HEV hev1, hev2, hev3;
ULONG ulPostCt1, ulPostCt2, ulPostCt3;
/*
* Define global variables.
*/
HAB hab; /* Primary thread anchor block.*/
HMQ hmq; /* Message queue handle.*/
HWND hwndFrame; /* Frame window handle.*/
HWND hwndClient; /* Client window handle.*/
HPS hpsClient;
HWND hwndMenu; /* Menu window handle.*/
SHORT cyClient; /* Height of client area.*/
SHORT cyClientIni; /* Height of initial client area.*/
CHAR szAppName[] = "PmChess"; /* Application name.*/
SHORT boarddraw[64]; /* Display copies of the board */
SHORT colordraw[64]; /* Needed because while computer is calculating*/
/* moves it updates board and color thus you can*/
/* not repaint the screen accuratly */
ULONG clrBackGround; /* color index for various colors */
ULONG clrBlackSquare;
ULONG clrWhiteSquare;
ULONG clrBlackPiece;
ULONG clrWhitePiece;
ULONG clrText, next = 1;
SHORT xchar, ychar;
SHORT coords = 1, rehash;
float ScaleFactor = 1.0; /* initial scaling factor */
SHORT clrcase; /* color case parameter */
extern HWND hComputerMove; /* def in create.c */
short Best;
USHORT *Bstline;
CHAR Bch;
CHAR szFullPath[80] = "";
extern unsigned int TTadd;
extern unsigned int ttbllimit;
/* Define local variables.*/
BOOL FirstSq = -1; /* Flag is a square is selected*/
INT GotFirst = FALSE;
INT UseBook = TRUE; /* use opening book as default */
INT EditActive = FALSE; /* Edit mode? */
INT User_Move = TRUE; /* User or computer's turn */
CHAR szClass[] = "PmChess"; /* Class name of main window procedure.*/
CHAR *CP[CPSIZE]; /* Class name of main window procedure.*/
char *ColorStr[2];
HPS hpsPieces; /* Memory PS of all chess pieces.*/
HPS hps;
/*
* Define prototypes of local routines.
*/
void FAR WndCreate(HWND hWnd);
void FAR WndPaint(HWND hWnd);
void FAR WndButton(HWND hWnd, ULONG msg, MPARAM mp1);
VOID _System calc1(ULONG);
VOID _System calc2(ULONG);
VOID _System calc3(ULONG);
VOID _System trddsp(ULONG);
void FAR WndDestroy(void);
BOOL GetFileName(HWND hWnd);
FNWP ChessProc;
FNWP AboutProc;
MRESULT EXPENTRY NotAvailableDlg( HWND hWnd, ULONG msg, MPARAM mp1,MPARAM mp2);
extern MRESULT EXPENTRY ColorProc( HWND hWnd, ULONG msg, MPARAM mp1,MPARAM mp2);
extern int ColorDialog(HWND hWnd, ULONG Param );
extern void UpdateChilds (void); /*these extern's can be moved to defs.h */
/***************************************************************************
*
* Routine: main(In, In)
*
* Remarks: This routine is then entry-point called by the OS/2 executive.
*
* Returns: None.
\****************************************************************************/
int main(short argc, char **argv)
{
QMSG qmsg;
ULONG ctlData;
POINTL ptl;
#ifdef ttblsz
ttblsize = ttblsz;
rehash = -1;
#endif /* ttblsz */
/* Allocate an anchor block and message queue to use PM services. */
hab = WinInitialize(0);
hmq = WinCreateMsgQueue(hab, 0);
/* Register the main window procedure. */
WinRegisterClass(hab, szClass, ChessProc, CS_SIZEREDRAW, 0);
/* Compute the idea client height. */
QueryBoardSize(&ptl);
cyClient = (SHORT)(ptl.y + WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER)
* 2L+ WinQuerySysValue(HWND_DESKTOP, SV_CYMENU)+
WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR) +
(LONG)ychar * 2L);
cyClientIni = cyClient;
/*
* Define the control fields for creating a standard frame window.
*/
ctlData = FCF_TITLEBAR | FCF_MINMAX | FCF_SIZEBORDER | FCF_SYSMENU |
FCF_MENU | FCF_TASKLIST | FCF_SHELLPOSITION |
FCF_ICON | FCF_ACCELTABLE;
/*
* Create our main frame window that makes us who we are.
*/
hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, &ctlData,
szClass, NULL, WS_VISIBLE, 0, IDR_PMCHESS,
&hwndClient);
/*
* Retrieve the menu handle to speed up future processing.
*/
hwndMenu = WinWindowFromID(hwndFrame, FID_MENU);
/*
* Size the frame window to our standard size.
*/
WinSetWindowPos(hwndFrame, 0, 32, 32,
(SHORT)(ptl.x+WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER)*2L+0L),
(SHORT)(ptl.y+WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER)*2+
WinQuerySysValue(HWND_DESKTOP, SV_CYMENU)+
WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR) + (LONG)ychar * 2L),
SWP_MOVE | SWP_SIZE);
/********** Initialize Help menu **********/
InitHelp();
/*************************************************************************
* Initialize the GNU Chess Logic...
\*************************************************************************/
init_main(hwndFrame);
player = opponent;
ShowSidetoMove();
Bstline = (USHORT *) malloc (MAXDEPTH * sizeof(USHORT));
/*************************************************************************
* The heart of an event driven system, the message dispatch loop.
**************************************************************************/
while (WinGetMsg(hab, &qmsg, 0, 0, 0)){
// DosEnterCritSec();
WinDispatchMsg(hab, &qmsg);
// DosExitCritSec();
}
/********************* destroy the help instance ********/
DestroyHelpInstance();
/**************************************************************************
* Release the anchor block and message queue as we are terminating.
***************************************************************************/
WinDestroyWindow(hwndFrame);
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
return 0;
}
/***************************************************************************
*
* WndProc: ChessProc(In, In, In, In)
*
* Remarks: This routine is then entry-point called by the OS/2 executive.
*
* Returns: Depends on message processed.
*/
MRESULT EXPENTRY ChessProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{ /******** beginning of ChessProc's *********/
HWND hwndOldMenu;
CHAR szBuf[64];
switch (msg)
{
case WM_CREATE:
WndCreate(hWnd);
/************************************/
/*It's bit awkward need three */
/*threads to do about the same thing*/
/************************************/
DosCreateEventSem(NULL, &hev1, 0,0);
tidcalc1 = _beginthread(calc1, NULL, 8192, NULL);
DosCreateEventSem(NULL, &hev2, 0,0);
tidcalc2 = _beginthread(calc2, NULL, 8192, NULL);
DosCreateEventSem(NULL, &hev3, 0,0);
tidcalc3 = _beginthread(calc3, NULL, 8192, NULL);
/*****************************************************************************/
/* This thread act as timer to signal the main process to update information */
/*****************************************************************************/
tiddsp = _beginthread(trddsp, NULL, 4096, NULL);
return (0);
/* case WM_DESTROY:
WndDestroy();
break;
*/
case WM_PAINT:
WndPaint(hWnd);
break;
case WM_ERASEBACKGROUND:
WinFillRect(HWNDFROMMP(mp1), PVOIDFROMMP(mp2), clrBackGround);
break;
case WM_SIZE:
cyClient = SHORT2FROMMP(mp2);
if (cyClient != 0)
{ ScaleFactor = (float)cyClient / cyClientIni;}
return (0);
case WM_BUTTON1DOWN:
WndButton(hWnd, msg, mp1);
break;
case WM_INITMENU:
if ( User_Move ) { /*Abort thinklook ahead*/
/* flag.timeout = true; */
/* flag.bothsides = false; */
}
if (!EditActive)
Init_Menus(hWnd, mp1, mp2);
break;
case WM_COMMAND:
switch (COMMANDMSG(&msg)->cmd /*SHORT1FROMMP(mp1)*/)
{
case IDM_FILE_NEW:
// if(!flag.bothsides)
// {
if (flag.easy && (player == opponent))
{
NewGame(hWnd);
if (UseBook) {
Book = BOOKFAIL;
} else {
Book = 0;
} /* endif */
UpdateDisplay (hWnd, 0, 0, 1, 0);
WinPostMsg(hWnd, UM_USER_MOVE, NULL, NULL);
} else {
flag.easy = true;
flag.timeout = true;
DosSleep(1500);
WinPostMsg ( hWnd, UM_NEW_GAME, NULL, NULL);
}
/* } else {
flag.bothsides = false;
flag.easy = true;
flag.timeout = true;
DosSleep(1500);
flag.timeout = true;
DosSleep(1500);
WinPostMsg ( hWnd, UM_NEW_GAME, NULL, NULL);
}
*/
break;
case IDM_FILE_OPEN:
if(GetFileName (hWnd))
GetGame (hWnd, szFullPath);
break;
case IDM_FILE_SAVE:
if(GetFileName (hWnd))
SaveGame (hWnd, szFullPath);
break;
case IDM_FILE_SAVEAS:
WinDlgBox( HWND_DESKTOP, hWnd,(PFNWP)NotAvailableDlg,
(HMODULE)0, IDD_NOTAVAIL, NULL);
break;
case IDM_FILE_LIST:
ListGame ();
break;
case IDM_FILE_EXIT:
WinPostMsg(hWnd,WM_QUIT,NULL,NULL);
return(MRESULT)TRUE;
case IDM_EDIT_BOARD:
EditActive = TRUE;
hwndOldMenu = WinWindowFromID(hwndFrame, FID_MENU);
WinLoadMenu(hwndFrame, 0, IDR_EDIT);
WinSendMsg(hwndFrame, WM_UPDATEFRAME, NULL, NULL);
WinDestroyWindow(hwndOldMenu);
break;
case IDM_EDIT_DONE:
EditActive = FALSE;
hwndOldMenu = WinWindowFromID(hwndFrame, FID_MENU);
WinLoadMenu(hwndFrame, 0, IDR_PMCHESS);
WinSendMsg(hwndFrame, WM_UPDATEFRAME, NULL, NULL);
WinDestroyWindow(hwndOldMenu);
GameCnt = 0;
Game50 = 1;
ZeroRPT ();
Sdepth = 0;
InitializeStats();
WinPostMsg(hWnd, UM_USER_MOVE, NULL, NULL);
break;
case IDM_EDIT_GAME:
/* ReviewDialog(hWnd); */
break;
case IDM_EDIT_UNDO:
if (GameCnt > 0)
Undo(hWnd);
break;
case IDM_EDIT_REMOVE:
if (GameCnt > 0){
Undo(hWnd);
Undo(hWnd);}
break;
case IDM_EDIT_MOVE:
flag.timeout = true;
break;
case IDM_EDIT_STOP:
flag.easy = true;
flag.timeout = true;
flag.bothsides =false;
break;
case IDM_EDIT_FORCE: /* no computer */
flag.force = !flag.force;
ShowPlayers();
WinPostMsg(hWnd, UM_USER_MOVE, NULL, NULL);
break;
case IDM_OPTIONS_TONE:
flag.beep = !flag.beep;
break;
case IDM_OPTIONS_COOR:
coords = !coords;
UpdateDisplay(hWnd, 0, 0, 1, 0);
break;
case IDM_OPTIONS_STATS:
if (flag.post)
{
WinSendMsg(hStats, WM_SYSCOMMAND, MPFROMSHORT(SC_CLOSE), NULL);
flag.post = false;
}
else
{
StatDialog(hWnd);
flag.post = TRUE;
}
break;
case IDM_OPTIONS_SPEED:
TestDialog(hWnd);
break;
case IDM_OPTIONS_HASH:
flag.hash = !flag.hash;
break;
case IDM_OPTIONS_BOTH:
flag.bothsides = !flag.bothsides;
if(flag.bothsides) flag.easy = true;
Sdepth = 0;
ShowPlayers();
WinPostMsg(hWnd, UM_USER_MOVE, NULL, NULL);
break;
case IDM_OPTIONS_BOOK:
UseBook = !UseBook;
if (UseBook) {
Book = BOOKFAIL;
} else {
Book = 0;
} /* endif */
break;
case IDM_OPTIONS_AWINDOW:
WinLoadString(hab, 0, IDS_SETAWIN, sizeof(szBuf), szBuf);
BAwindow = DoGetNumberDlg(hWnd, szBuf, BAwindow);
break;
case IDM_OPTIONS_BWINDOW:
WinLoadString(hab, 0, IDS_SETBWIN, sizeof(szBuf), szBuf);
BBwindow = DoGetNumberDlg(hWnd, szBuf, BBwindow);
break;
case IDM_OPTIONS_CONTEMP:
WinLoadString(hab, 0, IDS_SETCONTEMPT, sizeof(szBuf), szBuf);
contempt = DoGetNumberDlg(hWnd, szBuf, contempt);
break;
case IDM_SKILL_TIME:
if (TimeControlDialog(hWnd))
{
TCflag = (TCmoves > 1);
SetTimeControl();
}
break;
case IDM_SKILL_RANDOM:
if (dither == 0)
dither = 6;
else
dither = 0;
break;
case IDM_SKILL_EASY:
flag.easy = flag.easy^1;
break;
case IDM_SKILL_DEPTH:
WinLoadString(hab, 0, IDS_MAXSEARCH, sizeof(szBuf), szBuf);
MaxSearchDepth = DoGetNumberDlg(hWnd, szBuf, MaxSearchDepth);
break;
case IDM_SIDE_REVERSE:
flag.reverse = !flag.reverse;
UpdateDisplay(hWnd, 0, 0, 1, 0);
break;
case IDM_SIDE_SWITCH:
computer = otherside[computer];
opponent = otherside[opponent];
flag.force = false;
Sdepth = 0;
ShowPlayers();
WinPostMsg(hWnd, UM_COMPUTER_MOVE, NULL, NULL);
break;
case IDM_SIDE_BLACK:
computer = black;
opponent = white;
flag.force = false;
Sdepth = 0;
ShowPlayers();
WinPostMsg(hWnd, UM_COMPUTER_MOVE, NULL, NULL);
break;
case IDM_SIDE_WHITE:
computer = white;
opponent = black;
flag.force = false;
Sdepth = 0;
ShowPlayers();
WinPostMsg(hWnd, UM_COMPUTER_MOVE, NULL, NULL);
break;
case IDM_SIDE_REFRESH:
WinInvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_COLORS_BACKGROUND:
clrcase = IDM_COLORS_BACKGROUND;
ColorDialog( hWnd, 0L);
WinInvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_COLORS_BSQUARES:
clrcase = IDM_COLORS_BSQUARES;
ColorDialog( hWnd, 0L);
WinInvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_COLORS_WSQUARES:
clrcase = IDM_COLORS_WSQUARES;
ColorDialog( hWnd, 0L);
WinInvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_COLORS_BPIECES:
clrcase = IDM_COLORS_BPIECES;
ColorDialog( hWnd, 0L);
WinInvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_COLORS_WPIECES:
clrcase = IDM_COLORS_WPIECES;
ColorDialog( hWnd, 0L);
WinInvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_COLORS_TEXT:
clrcase = IDM_COLORS_TEXT;
ColorDialog( hWnd, 0L);
WinInvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_COLORS_DEFAULT:
SetStandardColors ();
WinInvalidateRect(hWnd, NULL, TRUE);
break;
case IDM_HINT:
GiveHint(hWnd);
break;
case IDM_HELP_INDEX:
HelpIndex();
break;
case IDM_HELP_EXT:
HelpGeneral();
break;
case IDM_HELP_DISPLAY:
HelpUsingHelp();
break;
case IDM_HELP_KEYS:
HelpKeys();
break;
case IDM_HELP_ABOUT:
WinDlgBox(HWND_DESKTOP, hWnd, AboutProc, 0, IDD_ABOUT, NULL);
break;
} /****************** end of switch for cmd (SHORT1FROMMP(mp1)) *********/
return (0);
case UM_EDITBOARD:
{
INT Square, First;
if ( flag.reverse )
{
First = 63 - ((SHORT1FROMMP(mp1) >> 8) & 0xff);
Square = 63 - (SHORT1FROMMP(mp1) & 0xff);
}
else
{
First = (SHORT1FROMMP(mp1) >>8) & 0xff;
Square = SHORT1FROMMP(mp1) & 0xff;
}
board[Square] = board[First];
color[Square] = color[First];
board[First] = no_piece;
color[First] = neutral;
UpdateDisplay(hWnd, First, Square, false, false);
}
break;
case UM_USER_MOVE:
{char tmp[20];
sprintf ( tmp, CP[84] /*"My move is %s"*/ ,(char *) mvstr[0]);
WinSetWindowText ( hComputerMove, tmp);
if ( flag.bothsides && !flag.mate )
{
ShowPlayers();
ShowSidetoMove ();
DosPostEventSem (hev2); /* start to calculate in autoplay mode */
}
else if (!flag.mate)
{
User_Move = TRUE;
ft = 0;
player = opponent;
ShowSidetoMove ();
/* if transposition table is filling start it over */
if(TTadd > ttbllimit)ZeroTTable();
/* Set up to allow computer to think while user takes move */
/* if we have a move for our opponent, and we are thinking on his time, and not in force mode */
if ( hint>0 && !flag.easy && Book == 0)
/* if the hint is a promotion don't do anything, we don't know what to promote to. */
if ((board[hint >> 8] != pawn) || ((row (hint & 0x3f) != 0) && (row (hint & 0x3f) != 7)))
{ DosPostEventSem (hev3); } /* if deep thinking is on start engine */
}
}
break;
case UM_USER_ENTERED_MOVE:
{
INT temp; USHORT mv; INT Square,First; CHAR str[10];
INT algbr_flag;
User_Move = FALSE;
player = opponent;
/* Fix coord's if user "reversed" board */
if ( flag.reverse ) {
First = 63 - ((SHORT1FROMMP(mp1) >>8) & 0xff);
Square = 63 - (SHORT1FROMMP(mp1) & 0xff);
} else {
First = (SHORT1FROMMP(mp1) >>8) & 0xff;
Square = SHORT1FROMMP(mp1) & 0xff;
}
/* Logic to allow selection for pawn promotion */
if ( (board[First] == pawn) &&( (Square <8) || (Square>55)) ) {
algbr_flag = promote + PromoteDialog (hWnd);
} else algbr_flag = 0;
algbr ( First, Square, algbr_flag);
strcpy ( str, mvstr[0] );
temp = VerifyMove ( hWnd, str, 0, &mv);
if ( temp && (mv != hint)) {
Sdepth = 0;
ft = 0;
ElapsedTime (1);
WinPostMsg( hWnd, UM_COMPUTER_MOVE, NULL, NULL);
} else if ( temp == TRUE) {
ElapsedTime (1);
// flag.musttimeout = true;
WinPostMsg ( hWnd, UM_COMPUTER_MOVE, NULL, NULL);
} else WinPostMsg ( hWnd, UM_USER_MOVE, NULL, NULL);
}
break;
case UM_COMPUTER_MOVE:
player = computer;
ShowSidetoMove ();
// ElapsedTime (1);
if (flag.force) {
computer = opponent;
opponent = computer ^ 1;
WinPostMsg( hWnd, UM_USER_MOVE, NULL, NULL);
}
else DosPostEventSem (hev1); /* start thinking */
return(MRESULT) TRUE;
// break;
case UM_NEW_GAME:
flag.bothsides = false;
flag.easy = false;
NewGame(hWnd);
if (UseBook) {
Book = BOOKFAIL;
} else {
Book = 0;
} /* endif */
UpdateDisplay (hWnd, 0, 0, 1, 0);
WinPostMsg(hWnd, UM_USER_MOVE, NULL, NULL);
break;
case UM_UPDATE_MSG:
UpdateClocks ();
ShowResults (Best, Bstline, Bch);
// if (hStats && (player == computer)) { /* cause lots of trouble */
// ShowCurrentMove (pntext, node->f, node->t); /* disabled */
// }
break;
} /* end of switch (msg) **********/
return (WinDefWindowProc(hWnd, msg, mp1, mp2));
} /******************* end of ChessProc ****************/
/****************************************************************************
*
* Routine: WndCreate(In):Static
*
* Remarks: This routine processed the WM_CREATE message from the main
* client window.
*
* Returns: None.
\*****************************************/
void FAR WndCreate(HWND hWnd)
{
FONTMETRICS fm;
hpsClient = WinGetPS(hWnd);
/*
* Load all the chess piece's bitmaps into a master memory ps for later.
*/
hpsPieces = LoadChessPieces(hab);
/*
* Load the diamensions of the default system font.
*/
GpiQueryFontMetrics(hpsClient, sizeof(fm), &fm);
xchar = (SHORT)fm.lEmInc;
ychar = (SHORT)fm.lMaxBaselineExt+(SHORT)fm.lExternalLeading;
Create_Children(hWnd, xchar, ychar);
GetStartupColors(szAppName);
/*
* Save the current color settings for the next time.
*/
SaveColors(szAppName);
WinReleasePS(hpsClient);
}
/****************************************************************************
*
* Routine: WndDestroy():Static
*
* Remarks: This routine processed the WM_DESTROY message from the main
* client window.
*
* Returns: None.
*/
// void WndDestroy()
// {
// /*
// * Save the current color settings for the next time.
// */
// SaveColors(szAppName);
// WinReleasePS(hpsClient);
// }
/****************************************************************************
*
* Routine: WndPaint(In):Static
*
* Remarks: This routine processed the WM_PAINT message from the main client
* client window.
*
* Returns: None.
*/
void WndPaint(HWND hWnd)
{
RECTL rcl;
/*
* Remember to properly repaint hi-lighted square.
*/
if (FirstSq != -1)
{
POINTL ptl;
RECTL rcl;
QuerySqOrigin(FirstSq % 8, FirstSq / 8, &ptl);
rcl.xLeft = ptl.x;
rcl.xRight = ptl.x + 48;
rcl.yTop = ptl.y;
rcl.yBottom = ptl.y - 48;
WinInvalidateRect(hWnd, &rcl, FALSE);
}
/*
* Retrieve the presentation space for drawing.
*/
hps = WinBeginPaint(hWnd, 0, &rcl);
/*
* Clear the background.
*/
WinFillRect(hps, &rcl, clrBackGround);
/*
* Draw the chess board.
*/
Draw_Board(hps, flag.reverse, clrBlackSquare, clrWhiteSquare);
/*
* Draw the coordinates if that option has been selected by the user.
*/
DrawCoords(hps, flag.reverse, clrBackGround, clrText, coords);
/*
* Draw in the pieces.
*/
DrawAllPieces(hps, hpsPieces, flag.reverse, boarddraw, colordraw,
clrBlackPiece, clrWhitePiece);
/*
* All done with painting the client area.
*/
WinEndPaint(hps);
/*
* If we have a selected square then hi-lighted it.
*/
if (FirstSq != -1)
HiliteSquare(hWnd, FirstSq);
}
/****************************************************************************
*
* Routine: WndButton(In):Static
*
* Remarks: This routine processed the various mouse button message from the
* main client window.
*
* Returns: None.
*/
void WndButton(HWND hWnd, ULONG msg, MPARAM mp1)
{
POINTL ptl;
SHORT Hit;
SHORT x, y;
hpsClient = WinGetPS(hWnd);
switch (msg)
{
case WM_BUTTON1DOWN:
/* If computer is thinking on human's time stop it at the first
button click. add test to ensure that "human" can't interupt
the computer from thinking through its turn. */
if(!flag.bothsides)
{
if (User_Move)
{
flag.timeout = true;
flag.bothsides = false;
}
/* Don't continue unless reason to */
if (!(EditActive || User_Move))
break;
ptl.x = SHORT1FROMMP(mp1);
ptl.y = SHORT2FROMMP(mp1);
CkdQueryHitCoords(hpsClient, &ptl, &x, &y);
if (x != -1 && y != -1)
Hit = y * 8 + x;
else
Hit = -1;
if ( Hit == -1 ){
if ( FirstSq != -1) {
UnHiliteSquare ( hWnd, FirstSq);
GotFirst = FALSE;
FirstSq = -1;
}
break;
}
if ( GotFirst ) {
UnHiliteSquare( hWnd, FirstSq);
GotFirst = FALSE;
if ( EditActive == TRUE) {
WinPostMsg(hWnd, UM_EDITBOARD, MPFROMSHORT((FirstSq<<8)|Hit), NULL);
} else if (User_Move == TRUE) {
WinPostMsg(hWnd, UM_USER_ENTERED_MOVE, MPFROMSHORT((FirstSq<<8)|Hit), NULL);
}
FirstSq = -1;
} else {
GotFirst = TRUE;
FirstSq = Hit;
HiliteSquare ( hWnd, Hit);
}
break;
}
}
WinReleasePS(hpsClient);
}
/*********************************************************************
* Name : NotAvailableDlg
*
* Description : Processes all messages sent to the NotAvailable
* Information dialog box.
*
* Concepts : Called for each message sent to the Product
* Information dialog box. The Product
* Information box only has a button control so
* this routine only processes WM_COMMAND
* messages. Any WM_COMMAND posted must have come
* from the Ok button so we dismiss the dialog
* upon receiving it.
*
* API's : WinDismissDlg
* WinDefDlgProc
*
* Parameters : hwnd - Window handle to which message is addressed
* msg - Message type
* mp1 - First message parameter
* mp2 - Second message parameter
*
* Returns : Dependent upon message sent
*
****************************************************************/
MRESULT EXPENTRY NotAvailableDlg( HWND hWnd, ULONG msg, MPARAM mp1,
MPARAM mp2)
{
switch(msg)
{
case WM_COMMAND:
/*
* No matter what the command, close the dialog
*/
WinDismissDlg(hWnd, TRUE);
break;
default:
return(WinDefDlgProc(hWnd, msg, mp1, mp2));
break;
}
return (MRESULT)0;
}
/********************** End of NotAvailable dialog procedure ****************/
MRESULT EXPENTRY AboutProc(HWND hDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
{
switch (msg)
{
case WM_COMMAND:
switch (SHORT1FROMMP(mp1))
{
case IDC_OK:
WinDismissDlg(hDlg, TRUE);
break;
}
return (0);
}
return (WinDefDlgProc(hDlg, msg, mp1, mp2));
}
/**************************************************************************
*
* Name : GetFileName()
*
* Description: gets the name of the save file
*
* Concepts: called when the user needs to supply a name for
* the file to be saved
*
* calls the standard file open dialog to get the
* file name.
*
* API's : WinLoadString
* WinFileDlg
*
* Parameters : [none]
*
* Return : TRUE if successful in getting a file name
* FALSE if not successful in getting a file name
*
*************************************************************************/
BOOL GetFileName(HWND hWnd)
{
FILEDLG fdg;
CHAR szTitle[80], szButton[80];
fdg.cbSize = sizeof(FILEDLG);
if(!WinLoadString(hab, 0, IDS_SAVE, 80, szTitle))
{
SMessageBox(hWnd, IDMSG_CANNOTLOADSTRING, IDS_CHESS);
return FALSE;
}
if(!WinLoadString(hab, 0, IDS_SAVE, 80, szButton))
{
SMessageBox(hWnd, IDMSG_CANNOTLOADSTRING, IDS_CHESS);
return FALSE;
}
fdg.pszTitle = szTitle;
fdg.pszOKButton = szButton;
fdg.ulUser = 0L;
fdg.fl = FDS_HELPBUTTON | FDS_CENTER | FDS_SAVEAS_DIALOG;
fdg.pfnDlgProc = (PFNWP)NULL; /* (PFNWP)TemplateSaveFilterProc;*/
fdg.lReturn = 0L;
fdg.lSRC = 0L;
fdg.hMod = (HMODULE)NULL;
fdg.usDlgId = IDD_FILESAVE;
fdg.x = 0;
fdg.y = 0;
fdg.pszIType = (PSZ)NULL;
fdg.papszITypeList = (PAPSZ)NULL;
fdg.pszIDrive = (PSZ)NULL;
fdg.papszIDriveList = (PAPSZ)NULL;
fdg.sEAType = (SHORT)0;
fdg.papszFQFilename = (PAPSZ)NULL;
fdg.ulFQFCount = 0L;
strcpy(fdg.szFullFile, szFullPath);
/* get the file */
if(!WinFileDlg(HWND_DESKTOP, hWnd, &fdg))
return FALSE;
if(fdg.lReturn != IDC_OK)
return FALSE;
/* copy file name and path returned into buffers */
strcpy(szFullPath, fdg.szFullFile);
return TRUE;
} /* End of GetFileName */
/*======================================== calc thread ===========*/
VOID calc1 (ULONG dummy)
{
HAB habt;
habt= WinInitialize(0);
for(;;){
DosWaitEventSem(hev1, SEM_INDEFINITE_WAIT);
if ( !(flag.quit || flag.mate || flag.force) ) {
SelectMove ( computer, 1);
if ( flag.beep ) WinAlarm(HWND_DESKTOP, WA_NOTE);
}
WinPostMsg( hwndClient, UM_USER_MOVE, NULL, NULL);
DosResetEventSem(hev1, &ulPostCt1);
}
}
VOID calc2 (ULONG dummy)
{
HAB habt;
habt= WinInitialize(0);
for(;;){
DosWaitEventSem(hev2, SEM_INDEFINITE_WAIT);
if ( !(flag.quit || flag.mate || flag.force) ) {
SelectMove ( opponent, 1);
if ( flag.beep ) WinAlarm(HWND_DESKTOP, WA_NOTE);
}
WinPostMsg( hwndClient, UM_COMPUTER_MOVE, NULL, NULL);
DosResetEventSem(hev2, &ulPostCt2);
}
}
VOID calc3 (ULONG dummy)
{
HAB habt;
INT tmp; USHORT mv; CHAR s[10];
habt= WinInitialize(0);
for(;;){
DosWaitEventSem(hev3, SEM_INDEFINITE_WAIT);
time0 = time ( NULL);
algbr ( hint>>8, hint&0x3f, false);
strcpy (s, mvstr[0]);
tmp = epsquare;
if ( VerifyMove (hwndClient, s,1, &mv) )
{
Sdepth = 0;/*419 added */
SelectMove ( computer, 2);
VerifyMove ( hwndClient, s, 2, &mv);
if ( Sdepth>0 ) Sdepth --;
}
ft = (time (NULL) - time0) ; /* *100?; since gnuchess4.0 time unit in 100th second */
epsquare = tmp;
DosResetEventSem(hev3, &ulPostCt3);
}
}
VOID trddsp (ULONG dummy)
{
for(;;){
DosSleep(1000); /* every 1 sec to update clocks */
WinPostMsg( hwndClient, UM_UPDATE_MSG, NULL, NULL);
}
}